package com.zwh.se.stream;

import com.zwh.se.collection.comparable_comparator.User;
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Stream是Java8中处理集合的关键抽象概念。
 * Stream API对集合数据进行操作，类似于使用SQL执行的数据库查询。也可以使用Stream API来并行执行操作。
 * 简而言之它提供了一种高效且易于使用处理数据的方式。
 */
public class StreamDemo {
    public static void main(String[] args) {
        List<User> users = Arrays.asList(
                new User("张三","zhangsan",18,9999),
                new User("赵四","zhaosi",36,8888),
                new User("王五","wanwu",26,7777),
                new User("赵六","zhaoliu",36,5555),
                new User("田七","tianqi",17,33333),
                new User("田七","tianqi",17,33333)
        );
        //创建流Stream的四种方式
        //方式一： 通过Collection系列集合提供的Stream()或parallelStream()
        Stream<User> stream = users.stream();
        //方式二：通过Arrays中的静态方法Stream（）获取数组流
        User[] users1 = new User[20];
        Arrays.stream(users1);
        //方式三：  通过Stream类中的静态方法of()
        Stream<String>stream3 = Stream.of("aa","bb");
        //方式四：   创建无限流：迭代/生成（迭代：一个数加三，限制数量10个生成：生成不限量随机数）
        Stream<Integer> stream4 = Stream.iterate(0,(x)->x+3);
        stream4.limit(10).forEach(System.out::println);
        //创建无限流，生成
//        Stream.generate(()->Math.random())
//                .forEach(System.out::println);
        System.out.println("----------------内部迭代：迭代器由Stream API完成,排除<35岁的------------------------");
        Stream<User> userStream = users.stream().filter(e -> e.getAge() > 35);
        userStream.forEach(System.out::println);
        System.out.println("-------------------排除工资<5000的，并且只显示2个人的信息---------------------");
        users.stream().filter(e->e.getSalary()>5000).limit(2).forEach(System.out::println);
        System.out.println("------------------排除资<5000的并跳过前两个人的信息工----------------------");
        users.stream().filter(e->e.getSalary()>5000).skip(2).forEach(System.out::println);
        System.out.println("--------------------排除工资<5000的并跳过前两个人的信息，并除去重复信息--------------------");
        users.stream().filter(e->e.getSalary()>5000).skip(2).distinct().forEach(System.out::println);
        System.out.println("--------------------将流中每个pinying字段的小写都换为大写--------------------");
        users.stream().map(User::getPingying).map(e->e.toUpperCase()).forEach(System.out::println);
        System.out.println("--------------------获取所有姓名--------------------");
        users.stream().map(User::getName).forEach(System.out::println);
        System.out.println("--------------------排序:如果年龄相等就按照姓名排，否则按照年龄排--------------------");
        users.stream().sorted((e1,e2)->{
            if (e1.getAge().equals(e2.getAge())){
                return e1.getName().compareTo(e2.getName());
            }else {
                return new Integer (e1.getAge()).compareTo(new Integer(e2.getAge())) ;
            }
        }).forEach(System.out::println);
        /**
         * allMatch-检查是否匹配所有元素
         * anyMatch-检查是否有一个元素匹配
         * noneMatch-检查是否没有匹配所有元素
         * findFirst-返回第一个元素
         * findAny-返回当前流中的任意元素
         * count-返回流中元素的总个数
         * max-返回流中最大值
         * min-返回流中最小值
         */
        System.out.println("--------------------是否有工资小于6000的用户--------------------");
        System.out.println(users.stream().anyMatch(x -> x.getSalary() < 6000));
        System.out.println("--------------------是否所有用户工资大于6000的用户--------------------");
        System.out.println(users.stream().allMatch(x -> x.getSalary() > 6000));
        System.out.println("--------------------是否没有用户工资大于50000--------------------");
        System.out.println(users.stream().noneMatch(x -> x.getSalary() > 50000));
        System.out.println("--------------------返回第一个值--------------------");
        System.out.println(users.stream().findFirst().get());
        System.out.println("--------------------返回任意值--------------------");
        System.out.println(users.stream().findAny().get());
        System.out.println("--------------------返回总数--------------------");
        System.out.println(users.stream().count());
        System.out.println("--------------------返回工资最多的用户--------------------");
        System.out.println(users.stream().max((x, y) -> x.getSalary().compareTo(y.getSalary())).get());
        System.out.println("--------------------返回工资最少的用户--------------------");
        System.out.println(users.stream().min((x, y) -> x.getSalary().compareTo(y.getSalary())).get());

        System.out.println("--------------------将薪资相加--------------------");
        Integer reduce = users.stream().map(User::getSalary).reduce(0, (x, y) -> x + y);
        System.out.println(reduce);
        System.out.println("--------------------将所有元素收集到set中--------------------");
        System.out.println(users.stream().collect(Collectors.toSet()));
        System.out.println("--------------------按年龄分组--------------------");
        Map<String,List<User>> map1 = users.stream()
                .collect(Collectors.groupingBy((e)->
                        {
                            if((e).getAge()<=35){
                                return "青年";
                            }else{
                                return"老年";
                            }
                        }
                )) ;
        System.out.println(map1);
        System.out.println("--------------------工资平均值--------------------");
        Double avg = users.stream()
                .collect(Collectors.averagingDouble(User::getSalary));
        System.out.println(avg);


    }

    @Data
    static
    class User{
        private String name;
        private String pingying;
        private Integer age;
        private Integer salary;

        public User(String name,String pingying, Integer age,Integer salary) {
            this.name = name;
            this.pingying = pingying;
            this.age = age;
            this.salary = salary;
        }
    }

}
